//
// Created by QU on 24-9-23.
//

#include "BaseNode.h"

BaseNode::BaseNode(const uint16_t payload_len)
    : m_payload_len(payload_len), m_payload(std::make_unique<std::byte[]>(payload_len))
{
    if (payload_len > MAX_PAYLOAD_SIZE)
    {
        throw std::invalid_argument("Payload size exceeds maximum allowed size");
    }
}

BaseNode::BaseNode(const std::byte payload_data[], const uint16_t payload_size)
{
    if (payload_size < MAX_HEADER_SIZE)
    {
        throw std::invalid_argument("Data too small for BaseNode");
    }

    // 从网络字节序（大端）转换为主机字节序
    uint16_t net_payload_len;
    std::memcpy(&net_payload_len, payload_data, sizeof(uint16_t));
    m_payload_len = boost::endian::big_to_native(net_payload_len);

    if (m_payload_len > payload_size - MAX_HEADER_SIZE || m_payload_len > MAX_PAYLOAD_SIZE)
    {
        throw std::invalid_argument("Invalid payload length");
    }

    // 直接复制 payload，不进行字节序转换
    m_payload = std::make_unique<std::byte[]>(m_payload_len);
    std::memcpy(m_payload.get(), payload_data + MAX_HEADER_SIZE, m_payload_len);
}

BaseNode::BaseNode(const SerializedData& serialized_data)
    : BaseNode(serialized_data.buffer.get(), serialized_data.length)
{
}

// 复制控制
BaseNode::BaseNode(const BaseNode& other)
    : m_payload_len(other.m_payload_len), m_payload(std::make_unique<std::byte[]>(other.m_payload_len))
{
    std::memcpy(m_payload.get(), other.m_payload.get(), other.m_payload_len);
}

BaseNode& BaseNode::operator=(const BaseNode& other)
{
    if (this != &other)
    {
        m_payload_len = other.m_payload_len;
        m_payload = std::make_unique<std::byte[]>(other.m_payload_len);
        std::memcpy(m_payload.get(), other.m_payload.get(), other.m_payload_len);
    }
    return *this;
}

BaseNode::BaseNode(BaseNode&& other) noexcept
    : m_payload_len(other.m_payload_len), m_payload(std::move(other.m_payload))
{
    other.m_payload_len = 0;
}

BaseNode& BaseNode::operator=(BaseNode&& other) noexcept
{
    if (this != &other)
    {
        m_payload_len = other.m_payload_len;
        m_payload = std::move(other.m_payload);
        other.m_payload_len = 0;
    }
    return *this;
}

BaseNode::SerializedData BaseNode::serialize() const
{
    auto buffer = std::make_unique<std::byte[]>(MAX_HEADER_SIZE + m_payload_len);

    // 转换 payload_len 到网络字节序（大端）
    const uint16_t net_payload_len = boost::endian::native_to_big(m_payload_len);
    std::memcpy(buffer.get(), &net_payload_len, sizeof(uint16_t));

    // 直接复制 payload，不进行字节序转换
    std::memcpy(buffer.get() + MAX_HEADER_SIZE, m_payload.get(), m_payload_len);

    return { std::move(buffer), static_cast<uint16_t>(MAX_HEADER_SIZE + m_payload_len) };
}

BaseNode BaseNode::deserialize(const std::byte data[], const uint16_t size)
{
    return BaseNode(data, size);
}

const std::byte* BaseNode::getNodePayloadPointer() const noexcept
{
    return m_payload.get();
}

uint16_t BaseNode::getNodePayloadSize() const noexcept
{
    return m_payload_len;
}

uint16_t BaseNode::getNodeFullSize() const noexcept
{
    return getNodePayloadSize() + MAX_HEADER_SIZE;
}

void BaseNode::setPayload(const std::byte* data, const uint16_t size)
{
    if (size > MAX_PAYLOAD_SIZE)
    {
        throw std::runtime_error("Payload size exceeds maximum allowed size");
    }

    m_payload_len = size;
    m_payload = std::make_unique<std::byte[]>(size);
    std::memcpy(m_payload.get(), data, size);
}

std::ostream& operator<<(std::ostream& os, const BaseNode& node)
{
    os << "getNodePayloadPointer: " << static_cast<const void*>(node.getNodePayloadPointer()) << "\n";
    os << "Payload length: " << static_cast<size_t>(node.getNodePayloadSize()) << "\n";
    os << "Payload (hex): ";

    const auto* payload = node.getNodePayloadPointer();
    os << std::hex << std::setfill('0');
    constexpr size_t OUTPUT_HEAD_TAIL = 16;
    const size_t payload_size = node.getNodePayloadSize();

    // 输出前半部分
    for (size_t i = 0; i < std::min(payload_size, OUTPUT_HEAD_TAIL); ++i)
    {
        if (i > 0) os << " ";
        os << std::setw(2) << static_cast<int>(payload[i]);
    }

    // 如果 payload 长度大于 output_head_tail * 2，则输出省略号和后半部分
    if (payload_size > OUTPUT_HEAD_TAIL * 2)
    {
        os << " ... ";
        for (size_t i = payload_size - OUTPUT_HEAD_TAIL; i < payload_size; ++i)
        {
            os << std::setw(2) << static_cast<int>(payload[i]) << " ";
        }
    }
    // 如果 payload 长度大于 output_head_tail 但小于 output_head_tail * 2，则继续输出剩余部分
    else if (payload_size > OUTPUT_HEAD_TAIL)
    {
        for (size_t i = OUTPUT_HEAD_TAIL; i < payload_size; ++i)
        {
            os << " " << std::setw(2) << static_cast<int>(static_cast<unsigned char>(payload[i]));
        }
    }

    os << std::dec << '\n'; // 恢复为十进制输出

    return os;
}


void BaseNode::clear() noexcept
{
    m_payload_len = 0;
    m_payload.reset(); // 释放资源
}
